<!-- author: xuett -->
<!-- date: 2025-06-23 15:11:12 -->
<!-- description:  -->
<template>
  <div ref="container" class="container" @click="selectCabinet">
    <div class="plane" :style="{ left: planePos.left, top: planePos.top, display: planePos.hasDisplay ? 'block' : 'none' }">
      <div>楼层：{{ curRackInfo.name }}</div>
      <div>编号：{{ curRackInfo.serialNumber }}</div>
      <el-button size="small" type="primary" @click="goDetail">查看详情</el-button>
    </div>
  </div>
</template>

<script setup>
import TWEEN from "@tweenjs/tween.js";
import Viewer from "@/hooks/viewer.js";
import postprocessing from "@/hooks/postprocessing.js";
import { createFloors } from "@/utils/createFloors";
import { adjustCameraToFitObject } from "@/utils/modelSize";
import createBasePlane from "@/utils/createBasePlane";

const $router = useRouter();

let viewerIns = null,
  postprocessingIns = null;
//鼠标点击的机柜
var curFloor = null;

const container = ref(null);
const state = reactive({
  showPostProcessing: true,
  // 信息框位置
  planePos: {
    hasDisplay: false,
    left: 0,
    top: 0
  },
  //选中机柜信息
  curRackInfo: {}
});
const { planePos, curRackInfo } = toRefs(state);

onMounted(() => {
  init();
});

var animationId;
onUnmounted(() => {
  // 清理资源
  cancelAnimationFrame(animationId);
  if (viewerIns) {
    viewerIns.dispose();
  }
});

//初始化
const init = async () => {
  viewerIns = new Viewer(container);

  // 创建后处理效果
  if (state.showPostProcessing) {
    postprocessingIns = new postprocessing(viewerIns, container);
  }

  let basePlane = createBasePlane(15, 15);
  viewerIns.scene.add(basePlane);

  const floorList = await createFloors([1, 2, 3, 4]);
  viewerIns.scene.add(...floorList);
  viewerIns.setRaycasterObjects(floorList);
  // 调整相机以适配模型
  adjustCameraToFitObject(floorList, viewerIns.camera, viewerIns.controls);

  // 处理窗口大小调整
  window.addEventListener("resize", () => onWindowResize());

  viewerIns.renderer.autoClear = false;
  animate();
};

// 窗口大小调整处理函数
const onWindowResize = () => {
  const width = container.value.clientWidth;
  const height = container.value.clientHeight;
  viewerIns.resize(width, height);
  postprocessingIns.resize(width, height);
};

// 动画循环
const animate = () => {
  // 使用后处理合成器渲染场景
  // if (state.showPostProcessing) {
  //   postprocessingIns.render();
  //   viewerIns.controls.update();
  // } else {
  //   //不使用后处理，直接渲染场景
  //   viewerIns.render();
  // }

  viewerIns.renderer.clear();
  viewerIns.camera.layers.set(1);
  postprocessingIns.composer.render();

  viewerIns.renderer.clearDepth();
  viewerIns.camera.layers.set(0);
  viewerIns.render();

  TWEEN.update(); // 更新 TWEEN 动画
  animationId = requestAnimationFrame(animate);
};

const selectCabinet = (mouseEvent) => {
  let intersectObj = viewerIns.getRaycasterIntersectObjects(mouseEvent);
  if (intersectObj && intersectObj.parent.name === "floor") {
    const floor = intersectObj.parent;
    // 切换该对象的高亮状态
    if (state.showPostProcessing) {
      postprocessingIns.toggleOutline(floor);
    }
    if (floor !== curFloor) {
      selectObject(floor, mouseEvent);
    }
  } else if (curFloor) {
    deselectObject();
  }
};

const selectObject = (object, mouseEvent) => {
  deselectObject(); // 取消之前选中的对象
  curFloor = object;

  //显示信息窗
  state.curRackInfo = object.userData;
  state.planePos.left = mouseEvent.clientX + "px";
  state.planePos.top = mouseEvent.clientY + "px";
  state.planePos.hasDisplay = Object.keys(object.userData).length ? true : false;
  curFloor.children.forEach((child) => {
    if (child.isMesh && child.material) {
      child.material.setValues({
        color: "#0000ff",
        opacity: 0.8
      });
    }
  });
};

const deselectObject = () => {
  state.planePos.hasDisplay = false;
  if (curFloor) {
    curFloor.children.forEach((child) => {
      if (child.isMesh && child.material) {
        child.material.setValues({
          color: "#aaaaaa",
          opacity: 1
        });
      }
    });
  }
};

// 查看详情
const goDetail = () => {
  $router.push("/iim-floor");
};
</script>

<style scoped lang="scss">
.container {
  position: absolute;
  width: 100%;
  height: 100%;
  .plane {
    position: absolute;
    top: 0;
    left: 0;
    background-color: rgba(0, 0, 0, 0.6);
    padding: 0 18px;
    transform: translate(12px, -100%);
    display: none;
    color: #fff;
    font-size: 16px;
    font-weight: normal;
    user-select: none;
  }
}
</style>
